@file:Suppress("UNUSED_PARAMETER")

package han.cirno.corrupt.modules.task.add

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import com.google.android.material.chip.Chip
import han.cirno.corrupt.R
import han.cirno.corrupt.data.DB
import han.cirno.corrupt.data.instances.UserTaskData
import han.cirno.corrupt.data.instances.UserTaskData.TaskData
import han.cirno.corrupt.data.instances.UserTaskData.TaskTag
import han.cirno.corrupt.databinding.ChipAddBinding
import han.cirno.corrupt.databinding.ChipNormalBinding
import han.cirno.corrupt.databinding.DialogTaskAddBinding
import han.cirno.corrupt.dialog.BottomPopDialog
import han.cirno.corrupt.util.ViewUtil
import java.util.Date

class TaskEditDialog(
    context:Context,
    private val bindTaskData: TaskData?,
    private val successCallback: (DismissType)->Unit) :
    BottomPopDialog<DialogTaskAddBinding>(context,DialogTaskAddBinding.inflate(LayoutInflater.from(context))){
    enum class DismissType {
        Discard, Submit, Remove
    }

    private var checkedTags: MutableList<TaskTag> =ArrayList()
    private var discard=false
    private var removeLock=true
    private val add = bindTaskData == null
    private var clickTimes=0

    init {
        setOnDismissListener{
            if(!add || discard)return@setOnDismissListener
            UserTaskData.draftTaskData=genData()
        }
        viewBinding.dialogChipEditTitle.setText(if(add)R.string.dialog_task_add_title else R.string.dialog_task_edit_title)
        viewBinding.dialogChipEditDescription.setText(if(add)R.string.dialog_task_add_description else R.string.dialog_task_edit_description)
        viewBinding.submitButton.setOnClickListener(this::onSubmitButtonClicked)
        viewBinding.discardButton.setOnClickListener(this::onDiscardButtonClicked)
        viewBinding.discardButton.setOnLongClickListener(this::onDiscardButtonLongClicked)
        viewBinding.removeButton.setOnClickListener(this::onRemoveButtonClicked)
        viewBinding.removeButton.setOnLongClickListener(this::onRemoveButtonLongClicked)
        viewBinding.removeButton.visibility=if(add)View.GONE else View.VISIBLE
        if (add)loadDraft()
        else load(bindTaskData)
        setCancelable(add)
        justUpdateChipLayout()
    }

    private fun reloadCheckedTags(){
        checkedTags.clear()
        viewBinding.tagChipGroup.checkedChipIds.forEach{id->
            val chip = viewBinding.tagChipGroup.findViewById<Chip>(id)
            val tag = chip.tag ?: return
            if (tag !is TaskTag)return
            checkedTags.add(tag)
        }
    }

    private fun updateChipLayout(){
        reloadCheckedTags()
        justUpdateChipLayout()
    }

    private fun justUpdateChipLayout(){
        viewBinding.tagChipGroup.removeAllViews()
        val inflater = LayoutInflater.from(context)
        for ((i,taskTag) in DB.getInstance().taskTagDao().getAllList().withIndex()) {
            val chip = genNormalChip(taskTag, inflater, i)
            if(chip.tag !is TaskTag)continue
            chip.isChecked=checkedTags.contains(chip.tag)
            viewBinding.tagChipGroup.addView(chip)
        }
        viewBinding.tagChipGroup.addView(genAddChip(inflater))
    }

    private fun genNormalChip(taskTag: TaskTag, inflater: LayoutInflater,id:Int) :Chip{
        val chip = ChipNormalBinding.inflate(inflater).chip
        chip.id=id
        chip.tag=taskTag
        chip.text=taskTag.tagName
        /*if (taskTag.tagColor!=null)
            TaskRecyclerViewAdapter.modifyChip(chip,context,taskTag.tagColor!!,false) FIXME*/
        chip.setOnLongClickListener{
            DB.getInstance().taskTagDao().delete(taskTag)
            //UserTaskData.taskTags.remove(taskTag)
            viewBinding.tagChipGroup.post(this::updateChipLayout)
            false
        }
        return chip
    }

    private fun genAddChip(inflater: LayoutInflater) :Chip{
        val chip = ChipAddBinding.inflate(inflater).chip
        chip.text=ViewUtil.getString(R.string.dialog_task_chip_add_chip_text)
        chip.setOnClickListener{
            val dialog=ChipEditDialog(context){taskTag->
                DB.getInstance().taskTagDao().insert(taskTag)
                //UserTaskData.taskTags.add(taskTag)
                updateChipLayout()
            }
            dialog.show()
        }
        return chip
    }

    private fun onRemoveButtonClicked(v: View){
        if (add) return
        if (removeLock) {
            viewBinding.removeButton.setText(R.string.dialog_task_remove_warning_1)
            removeLock = false
        }
    }

    @Suppress("SameReturnValue")
    private fun onRemoveButtonLongClicked(v: View):Boolean{
        if (add) return false
        if (removeLock) {
            viewBinding.removeButton.setText(R.string.dialog_task_remove_warning_2)
            removeLock = false
            return false
        }
        successCallback(DismissType.Remove)
        dismiss()
        return false
    }

    private fun onDiscardButtonClicked(v: View) {
        clickTimes++
        val waringTextResId =
            when (clickTimes) {
                in 0..30 -> R.string.dialog_task_discard_warning
                in 31..60 -> R.string.dialog_task_discard_warning_2
                in 61..90 -> R.string.dialog_task_discard_warning_3
                in 91..120 -> R.string.dialog_task_discard_warning_4
                in 121..150 -> R.string.dialog_task_discard_warning_5
                in 151..180 -> R.string.dialog_task_discard_warning_6
                else -> R.string.dialog_task_discard_warning_7
            }
        viewBinding.discardButton.setText(waringTextResId)
    }

    private fun onDiscardButtonLongClicked(v:View)=run {
        if (add) UserTaskData.draftTaskData=null
        discard=true
        successCallback(DismissType.Discard)
        dismiss()
        false
    }

    private fun onSubmitButtonClicked(v:View){
        if (viewBinding.titleInput.text.toString().isEmpty()) {
            viewBinding.titleInput.error = context.getText(R.string.dialog_task_error_blank_title)
            return
        }
        val taskData = genData()
        discard = true
        if (add) {
            DB.getInstance().taskDataDao().insert(taskData)
            //UserTaskData.taskData.add(0, taskData)
        } else {
            bindTaskData!!.copyToThis(taskData)
        }
        successCallback(DismissType.Submit)
        dismiss()
    }

    private fun genData():TaskData{
        val taskData = TaskData()
        viewBinding.tagChipGroup.checkedChipIds.forEach{id->
            if(id==-1)return@forEach
            val chip = viewBinding.tagChipGroup.findViewById<Chip>(id)
            taskData.tags.add((chip.tag as TaskTag).uid)//TODO fixit
        }
        taskData.name=viewBinding.titleInput.text.toString()
        taskData.description=viewBinding.descriptionInput.text.toString()
        taskData.createdTime=Date()
        taskData.finishedTime=null
        taskData.isCompleted=false
        taskData.isSubmitted=false
        return taskData
    }

    private fun loadDraft(){
        val draftTaskData : TaskData? = UserTaskData.draftTaskData
        load(draftTaskData)
    }

    private fun load(data: TaskData?){
        if (data==null)return
        viewBinding.titleInput.setText(data.name?:"")
        viewBinding.descriptionInput.setText(data.description?:"")
        //checkedTags=data.tags todo fix it
    }

}